package com.jkt.rms.businessservice.impl;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.BeanUtils;

import com.jkt.rms.business.ModuleMaster;
import com.jkt.rms.business.SystemRole;
import com.jkt.rms.businessservice.RoleBusinessService;
import com.jkt.rms.cache.RMSCache;
import com.jkt.rms.commons.utils.EqualityUtils;
import com.jkt.rms.commons.utils.RMSException;
import com.jkt.rms.commons.utils.ServiceLocator;
import com.jkt.rms.constants.IConstants;
import com.jkt.rms.dataservice.RoleDataService;
import com.jkt.rms.vo.OptionVO;
import com.jkt.rms.vo.SystemRoleLinkupVO;
import com.jkt.rms.vo.SystemRoleVO;

public class RoleBusinessServiceImpl  implements RoleBusinessService {
	
	private RoleDataService roleDataService; 
	private RMSCache cache;
	@Override
	public SystemRole isRoleExist(String userName) {
		SystemRole sysRole = roleDataService.isRoleExist(userName);		
		return sysRole;
	}
	private RMSCache getCache() {
		cache = ServiceLocator.getServiceLocator().locate("cacheService");
		return cache;
	}
	 
	@Override
	public SystemRole saveRole(SystemRoleVO sysroleVO) throws RMSException {
		String str = "";
		if(!sysroleVO.getRoleName().toUpperCase().startsWith(IConstants.ROLE_PREFIX)){
			 str = IConstants.ROLE_PREFIX+sysroleVO.getRoleName();
			sysroleVO.setRoleName(str);
		}
		SystemRole systemRole = isRoleExist(sysroleVO.getRoleName().toUpperCase());
			if(systemRole == null) {
				final SystemRole sysRole = new SystemRole();
				EqualityUtils.copyProperties(sysRole, sysroleVO);
				sysRole.setUpdatedDate(new Timestamp(System.currentTimeMillis()));
				sysRole.setStatus('Y');
				roleDataService.saveRole(sysRole);
				 getCache();
				 cache.refersh(RMSCache.SYSROLECACHE);
			}
			return systemRole;
	}

	public void setRoleDataService(RoleDataService roleDataService) {
		this.roleDataService = roleDataService;
	}

	public List<SystemRoleVO> findAllRoles() throws RMSException {
		RMSCache cache = ServiceLocator.getServiceLocator().locate("cacheService");
		List<SystemRole> systemRoleList =  cache.getAllSystemRoles();
		SystemRoleVO sysRoleVO;
		List<SystemRoleVO> listRoleVO = new ArrayList<SystemRoleVO>();
		if(systemRoleList != null && systemRoleList.size() > 0) {
			for (SystemRole systemRole : systemRoleList) {
				sysRoleVO = new SystemRoleVO();
				sysRoleVO.setRoleName(systemRole.getRoleName());
				listRoleVO.add(sysRoleVO);
			}
		}
		return listRoleVO;
	}
	
	public List<String> findAllRoleNames()
	{
		return roleDataService.findAllRoleNames();
	}
	
	public List<ModuleMaster> findAllModules()
	{
		return roleDataService.findAllModules();
	}
	
	public SystemRoleLinkupVO findAllLinkupRoles() throws RMSException {
		
		SystemRoleLinkupVO 		sysrolelinkupvo	= new SystemRoleLinkupVO();
		List<OptionVO<String>> 	optionsList 	= new ArrayList<OptionVO<String>>();
		Map<String,String>  	moduleMap    	= new HashMap<String,String>();
		try{
			
			// Find all role names for dropdown and add to options.
			List<String> roleElements = findAllRoleNames();
			for(String roleElement : roleElements)
				   optionsList.add(new OptionVO<String>(roleElement, roleElement));
			
			// Find all modules and add to Module Map
			List<ModuleMaster>  	modules = findAllModules();
			for(ModuleMaster module: modules)
				moduleMap.put(Integer.toString(module.getModule_id()), module.getModuleName());
			
			sysrolelinkupvo.setRoles(optionsList);
			sysrolelinkupvo.setModuleMap(moduleMap);
		}
		catch(Exception e)
		{throw new RMSException(e.getCause());}
		
		return sysrolelinkupvo;
	}
	
	public SystemRoleLinkupVO  findModuleByRole(SystemRoleLinkupVO sysrolelinkupvo) throws RMSException
	{
		
		try
		{
			SystemRoleLinkupVO  newSysrolelinkupvo = findAllLinkupRoles(); 
			SystemRole sysrole  				   = roleDataService.isRoleExist(sysrolelinkupvo.getRoleName());
			
			List<String> selectedList = new ArrayList<String>();
			
			// Reload the view object with all the properties.
			sysrolelinkupvo.setModuleMap(newSysrolelinkupvo.getModuleMap());
			sysrolelinkupvo.setRoles(newSysrolelinkupvo.getRoles());
			
			// Add all the modules in the check box for given input role.
			for(ModuleMaster module : sysrole.getModules())
				selectedList.add(Integer.toString(module.getModule_id()));
			
			sysrolelinkupvo.setModuleSelectedList(selectedList);	
		}
		catch(Exception e)
		{throw new RMSException(e.getCause());}
		
		return sysrolelinkupvo;
	}
	
	public void saveModulesForRole(SystemRoleLinkupVO sysrolelinkupvo) throws RMSException
	{
		try
		{
			// Get the Role object from db & create new module set on the basis of checked modules.
			SystemRole sysrole    		= roleDataService.isRoleExist(sysrolelinkupvo.getRoleName());
			Set<ModuleMaster> modules 	= new HashSet<ModuleMaster>();

			if(null != sysrolelinkupvo.getModuleSelectedList())
				for(String module_id : sysrolelinkupvo.getModuleSelectedList())
				    modules.add(roleDataService.getModuleById(Integer.parseInt(module_id)));	
				
			sysrole.setModules(modules);
			roleDataService.saveorUpdateRole(sysrole);
		}	
		catch(Exception e)
		{throw new RMSException(e.getCause());}
	
		return;
	}
}
